<?php
/**
 * This file is part of webman.
 *
 * Licensed under The MIT License
 * For full copyright and license information, please see the MIT-LICENSE.txt
 * Redistributions of files must retain the above copyright notice.
 *
 * @author    walkor<walkor@workerman.net>
 * @copyright walkor<walkor@workerman.net>
 * @link      http://www.workerman.net/
 * @license   http://www.opensource.org/licenses/mit-license.php MIT License
 */

namespace app\process;

use SplFileInfo;
use support\Container;
use support\utils\FileUtil;
use Webman\RedisQueue\Client;

/**
 * 根据 Webman\RedisQueue\Process\Consumer 改的支持多个目录合并到一组消息队列进程消费
 * Class Consumer
 * @package process
 */
class Consumer
{
    /**
     * @var array
     */
    protected $_consumerDirs = [];

    /**
     * @var array
     */
    protected $_consumers = [];

    /**
     * Consumer constructor.
     * @param array $consumer_dirs
     */
    public function __construct(array $consumer_dirs = [])
    {
        $this->_consumerDirs = $consumer_dirs;
    }

    /**
     * onWorkerStart.
     */
    public function onWorkerStart()
    {
        FileUtil::fileIterator($this->_consumerDirs, function ($fileUrl, SplFileInfo $fileInfo) {
            $ext = $fileInfo->getExtension();
            if ($ext === 'php') {
                $class = str_replace('/', "\\", substr(substr($fileUrl, strlen(base_path())), 0, -4));
                if (is_a($class, 'Webman\RedisQueue\Consumer', true)) {
                    $consumer = Container::get($class);
                    $connection_name = $consumer->connection ?? 'default';
                    $queue = $consumer->queue;
                    $this->_consumers[$queue] = $consumer;
                    $connection = Client::connection($connection_name);
                    $connection->subscribe($queue, [$consumer, 'consume']);
                    if (method_exists($connection, 'onConsumeFailure')) {
                        $connection->onConsumeFailure(function ($exeption, $package) {
                            $consumer = $this->_consumers[$package['queue']] ?? null;
                            if ($consumer && method_exists($consumer, 'onConsumeFailure')) {
                                return call_user_func([$consumer, 'onConsumeFailure'], $exeption, $package);
                            }
                        });
                    }
                }
            }
        });

    }
}
